﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Media.Effects;
using PRScreenWithKinect.UI;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using System.Threading;
using System.Timers;
using PRScreenWithKinect.Model;


namespace PRScreenWithKinect
{
	/// <summary> TEWSSETTTTTTss
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
  
        private UserControl content;
        private BlurEffect _blurEffect;
        private MarqueeText marquee;
        private PRScreenWithKinect.UI.Menu menu;
        private const double nonFocusOpacitiy = GlobalConfig.NON_FOCUS_OPACITY;
		private Storyboard holdTimer ;
        private Storyboard holdLTimer;
        private Boolean isHumanVisible;
        private Storyboard bouceFX;
        private DispatcherTimer waitToStartHold;
        private Kinect kinect;
        private DataFactory datafactory;
        private System.Timers.Timer billboard_timer;
        private bool isGestureEnable = GlobalConfig.USING_GESTURE;
        private bool isLoadFinished = false;
        /// Adjust Pointer Position with left & top margion ( Kinect position start (0,0) but Screen start (446,0) )
        int left_margin = 446;
        int top_margin = 0;

        /// Hand Mode 
        /// LeftHand : -1
        /// Free : 0 
        /// RightHand : 1 
        enum HandMode
        {
            LeftHand = -1 , FreeHand = 0 ,RightHand= 1
        }
        private HandMode  _handmode = HandMode.FreeHand; 

		public MainWindow()
		{
        /// Test Version Control
			this.InitializeComponent();

            //// Call DataFactory 
            datafactory = DataFactory.Instance;

            /// Set up Billboard Timer 
            billboard_timer = new System.Timers.Timer(GlobalConfig.PERIOD_TO_PLAY_BILLBOARD);
            billboard_timer.Enabled = true;
            billboard_timer.Elapsed += new ElapsedEventHandler(billboard_timer_Elapsed);
           
            // Initial Effect 
            _blurEffect = new BlurEffect();
            _blurEffect.Radius = GlobalConfig.BLUR_FX_RADIUS;

            /// Add MarqueeText to MarqueePanel 
            content = new BackgroundUI();
            marquee = new MarqueeText();
            menu = new UI.Menu(this);
 

            MarqueePanel.Children.Add(marquee);
            HomeMenu.Children.Add(menu);
           
            //// Create BouceFX ; 
            bouceFX = (Storyboard)this.Resources["BouceFX"];

            //// Create Loading Story ;
            //_loading = (Storyboard)this.Resources["loadingStory"];
            //_loading.Begin();



			/// Hold Timer 
            /// Right Hand Storyboard
			holdTimer = (Storyboard)this.Resources["HoldTime"];
            holdTimer.Completed += new EventHandler(holdTimer_Completed);
            /// Left Hand Storyboard
            holdLTimer = (Storyboard)this.Resources["LHoldTime"];
            holdLTimer.Completed += new EventHandler(holdTimer_Completed);


            /// When hold wait 0.2 sec to start Count down hold event
            waitToStartHold = new DispatcherTimer();
            waitToStartHold.Interval = new TimeSpan(0, 0, 0, 0, GlobalConfig.TIME_BEFORE_HOLD);
            waitToStartHold.Tick += new EventHandler(waitToStartHold_Tick);


            if (isGestureEnable)
            {
                //// Kinect Set up
                kinect = new Kinect(548, 600);
                Handler.RHandMove += new KinectHandler(Handler_RHandMove);
                Handler.LHandMove += new KinectHandler(Handler_LHandMove);
                Handler.SwipeLeft += new KinectHandler(Handler_SwipeLeft);
                Handler.SwipeRight += new KinectHandler(Handler_SwipeRight);
                Handler.HumanIn += new KinectHandler(Handler_HumanIn);
                Handler.HumanOut += new KinectHandler(Handler_HumanOut);
                Handler.SwipeUp += new KinectHandler(Handler_SwipeUp);
                Handler.SwipeDown += new KinectHandler(Handler_SwipeDown);
                Handler.ColorFrame += new KinectHandler(Handler_ColorFrame);
                Handler.RHandIdle += new KinectHandler(Handler_HandIdle);
                Handler.RHandActive += new KinectHandler(Handler_HandActive);
                Handler.LHandIdle += new KinectHandler(Handler_LHandIdle);
                Handler.LHandActive += new KinectHandler(Handler_LHandActive);

            }


            System.Threading.Thread newThread;
            newThread = new System.Threading.Thread(waitForFirstData);

            newThread.Start();
 

            
         
		}

        private void waitForFirstData()
        {
            while (true)
            {
                if (DataFactory.Instance.billboard != null)
                {
                    break;
                }
                //    Console.WriteLine("Null Billboard");
            }
            Console.WriteLine("Load Data Finished");
            Dispatcher.Invoke(new Action(delegate()
            {
                _Loading.Visibility = Visibility.Hidden;
                
                ///// Open Billboard when startup ; 
                openContent("Billboard");
                
                isLoadFinished = true;
                billboard_timer.Start();
                
            }));

            

        }

        void Handler_LHandActive(KinectEventArgs eKi)
        {
           LhandControl.Visibility = Visibility.Visible;
        }

        void Handler_LHandIdle(KinectEventArgs eKi)
        {
            LhandControl.Visibility = Visibility.Hidden;
        }

     

        void Handler_HandActive(KinectEventArgs eKi)
        {
             RhandControl.Visibility = Visibility.Visible;
        }

        void Handler_HandIdle(KinectEventArgs eKi)
        {
            RhandControl.Visibility = Visibility.Hidden;
        }

        void Handler_ColorFrame(KinectEventArgs eKi)
        {
            //Console.WriteLine("Color Frame");
            KinectImage.Source = eKi.imageSrc;
        }
        int i=1;
        void Handler_SwipeDown(KinectEventArgs eKi)
        {
            if (isHold) return;//if hand is end on any button (dont do any action)
            if (!menu.IsToggle && isLoadFinished)
            {
                menu.slideDown();
                blurElement(true);

            }
        }
        
        void Handler_SwipeUp(KinectEventArgs eKi)
        {
            if (isHold) return;
            if (menu.IsToggle)
            {
                menu.slideUp();
                blurElement(false);

            }
        }

        void billboard_timer_Elapsed(object sender, ElapsedEventArgs e)
        {


            Dispatcher.Invoke(DispatcherPriority.Normal,
                    new Action(() =>
                    {
                        if (content.GetType() != typeof(BillBoard))
                        {
                            openContent("Billboard");
                
                        }
                        if (menu.IsToggle)
                        {
                            menu.slideUp();
                        }
                        Storyboard st = (Storyboard)this.Resources["PointerFadeOut"];
                        st.Begin();
                        BillBoard b = (BillBoard)content;
                        b.startAutoPlay();
                        billboard_timer.Stop();
                    }));
               
           
       
          
        }

        void Handler_HumanOut(KinectEventArgs eKi)
        {
            //throw new NotImplementedException();
            humanOut();
        }

        void Handler_HumanIn(KinectEventArgs eKi)
        {
           //s throw new NotImplementedException();
            humanIn();
        }

        void Handler_SwipeRight(KinectEventArgs eKi)
        {
            if (!menu.IsToggle )
            {
                ((UserControlInterfaceForGesture)content).swipeRight();
            }
        }

        void Handler_SwipeLeft(KinectEventArgs eKi)
        {

            if (!menu.IsToggle)
            {
                ((UserControlInterfaceForGesture)content).swipeLeft();
            }
        
        }

        void Handler_LHandMove(KinectEventArgs eKi)
        {

            Dispatcher.BeginInvoke(new ThreadStart(delegate()
            {

                //  Console.WriteLine("Hand Position : " + eKi.RHandPosition.X + "  " + eKi.RHandPosition.Y);
                Point p = eKi.LHandPosition;
                Point LhandRelativePoint = PointerCanvas.TransformToAncestor(this).Transform(new Point(0, 0));
                Canvas.SetLeft(LhandControl, p.X + left_margin - LhandRelativePoint.X - RhandControl.Width / 2);
                Canvas.SetTop(LhandControl, p.Y + top_margin - LhandRelativePoint.Y - RhandControl.Height / 2);
                checkPointerHit(HandMode.LeftHand, new Point(p.X + left_margin, p.Y + top_margin));
            }));
        }
        void Handler_RHandMove(KinectEventArgs eKi)
        {
            //sthrow new NotImplementedException();
            textBox1.Text = eKi.RHandPosition.Y+"";
            Dispatcher.BeginInvoke(new ThreadStart(delegate()
                      {
 
                        //  Console.WriteLine("Hand Position : " + eKi.RHandPosition.X + "  " + eKi.RHandPosition.Y);
                          Point p = eKi.RHandPosition;
                          Point RhandRelativePoint = PointerCanvas.TransformToAncestor(this).Transform(new Point(0, 0));
                          Canvas.SetLeft(RhandControl, p.X + left_margin - RhandRelativePoint.X - RhandControl.Width / 2);
                          Canvas.SetTop(RhandControl, p.Y+top_margin - RhandRelativePoint.Y - RhandControl.Height / 2);
                          checkPointerHit(HandMode.RightHand,new Point(p.X +left_margin, p.Y+top_margin));
                      }));

        
        }


        void waitToStartHold_Tick(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            waitToStartHold.Stop();
            if (_handmode == HandMode.LeftHand)
            {
                holdLTimer.Begin();
            }
            else if(_handmode == HandMode.RightHand)
            {
                holdTimer.Begin();
            }
           
           
        }

      

        void holdTimer_Completed(object sender, EventArgs e)
        {
            finishedHold();

            
        }


        /// Test Section 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            openContent("AboutFac");
        }

        
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
        openContent("Billboard");
          
           
        }
        public void openContent(String c)
        {
            UserControl prevContent = content; 
            if (c.Equals("Billboard"))
            {
                content= new BillBoard();
                marquee.changeBackground(1);
              
               // isLoadFinished = true;
            }else if(c.Equals("News")){
                content = new News();
                marquee.changeBackground(0);

            }else if(c.Equals("Location")){
                content = new Location();
                marquee.changeBackground(0);
            }else if(c.Equals("AboutFac")){
                content = new AboutFac() ; 
                marquee.changeBackground(0);

            }
            else if (c.Equals("GuestBook"))
            {
                content = new GuestBook();
                marquee.changeBackground(0);
            }
            else if (c.Equals("Gallery"))
            {
                content = new Gallery();
                marquee.changeBackground(0);
            }
            else if (c.Equals("Help"))
            {
                content = new Help();
                marquee.changeBackground(0);
            }
          

               
              MainPanel.Children.Add(content);
               
              Storyboard.SetTarget(bouceFX.Children[0], content);
              Storyboard.SetTargetProperty(bouceFX.Children[0], new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)"));
              bouceFX.Begin();

            
              if (MainPanel.Children.Count > 1)
              {
                  MainPanel.Children.RemoveAt(0);
              }
            

            
        }

        public void blurElement(bool st)
        {
            if (st)
            {
                content.Effect = _blurEffect;
                marquee.Effect = _blurEffect;
                content.Opacity = nonFocusOpacitiy;
                marquee.Opacity = nonFocusOpacitiy;
               // HomeMenuIcon.Effect = _blurEffect;
            }
            else
            {
                marquee.Opacity = 1;
                content.Opacity = 1;
                content.Effect = null;
                marquee.Effect = null;
            }
         
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            toggleHomeMenu();

        }
        private void toggleHomeMenu()
        {
            if (menu.IsToggle)
            {
                kinect.doMenuSelected(false);
                menu.slideUp();
                blurElement(false);
            }
            else
            {
                kinect.doMenuSelected(true);
                blurElement(true);
                //HomeMenu.Visibility = Visibility.Visible;
                menu.slideDown();
            }
     
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            openContent("News");    
        }

        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            openContent("Location");
        }

        private void Blur(object sender, System.Windows.RoutedEventArgs e)
        {
        	// TODO: Add event handler implementation here.
			    blurElement(true);
        }

        private void OpenGuestBook(object sender, System.Windows.RoutedEventArgs e)
        {
        	// TODO: Add event handler implementation here.
            openContent("GuestBook");
			
        }

        private void GalleryPress(object sender, System.Windows.RoutedEventArgs e)
        {
        	// TODO: Add event handler implementation here.
			openContent("Gallery");
        }

        private UIElement prevObjectHit; 
        
        private void Main_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            /// When Use Mouse 
            ///  RHand Pointer follow by relative postion of 'PointerCanvas' 
            if (!isGestureEnable)
            {
                Point p = e.GetPosition(this);

                Point RhandRelativePoint = PointerCanvas.TransformToAncestor(this).Transform(new Point(0, 0));
                Canvas.SetLeft(RhandControl, p.X - RhandRelativePoint.X+200*(GlobalConfig.FIRST_HAND-1) - RhandControl.Width / 2);
                Canvas.SetTop(RhandControl, p.Y - RhandRelativePoint.Y - RhandControl.Height / 2);

                Point LhandRelativePoint = PointerCanvas.TransformToAncestor(this).Transform(new Point(0, 0));
                Canvas.SetLeft(LhandControl, p.X - LhandRelativePoint.X - 200*GlobalConfig.FIRST_HAND - LhandControl.Width / 2);
                Canvas.SetTop(LhandControl, p.Y - LhandRelativePoint.Y - LhandControl.Height / 2);

            }

            int first_hand = GlobalConfig.FIRST_HAND; 
            if (first_hand == 0)
            { // Use Left Hand
                checkPointerHit(HandMode.LeftHand, e.GetPosition(this));
            }
            else
            { // Use Right Hand
                checkPointerHit(HandMode.RightHand, e.GetPosition(this));
            }
           
            
        }

        private void checkPointerHit(HandMode h,Point p){

            if ((_handmode == HandMode.FreeHand || _handmode ==h )&& isLoadFinished)
            {


               // Console.WriteLine("Check Pointer Hit with HandMode = " + h);

                UIElement currentObjectHit = null;


                ///// 1st Check Home Menu Icon 
                // HitTestResult hitResult = VisualTreeHelper.HitTest(HomeMenuIcon,e.GetPosition(HomeMenuIcon));
                Point relativePoint = HomeMenuIcon.TransformToAncestor(this)
                                  .Transform(new Point(0, 0));
                Point absPoint = p;
                Point delta = new Point(absPoint.X - relativePoint.X, absPoint.Y - relativePoint.Y);
                HitTestResult hitResult = VisualTreeHelper.HitTest(HomeMenuIcon, delta);

                if (isHumanVisible)
                {

                    if (hitResult != null)
                    {
                        // Console.WriteLine("Hit Result HomeMenuIcon");
                        currentObjectHit = HomeMenuIcon;
                    }
                    else
                    {
                        if (menu.IsToggle && menu.hitTest(p, this))
                        {
                            ///// 2nd Check Home Menu 
                            currentObjectHit = menu;

                        }
                        else
                        {
                            //// 3rd Check on UI Controll 
                            UserControlInterfaceForGesture obj = (UserControlInterfaceForGesture)content;
                            if (!menu.IsToggle && obj.hitTest(p, this))
                            {
                                currentObjectHit = content;
                            }

                        }

                    }
                    //// Check for Start Hold 
                    if (currentObjectHit != null)
                    {
                        if (!currentObjectHit.Equals(prevObjectHit))
                        {
                            setHandMode(h);
                            startHold(h);
                        }
                        prevObjectHit = currentObjectHit;
                    }
                    else
                    {
                        
                        endHold();
                        prevObjectHit = null;

                    }
                }
            }
        }

        private void setHandMode(HandMode h)
        {
            if (h == HandMode.LeftHand)
            {
                RhandControl.Opacity = GlobalConfig.NON_FOCUS_OPACITY;
            }else if( h == HandMode.RightHand){
                LhandControl.Opacity = GlobalConfig.NON_FOCUS_OPACITY;
            }else{
                LhandControl.Opacity = 1;
                RhandControl.Opacity = 1;
            }
            _handmode = h;
        }
        private bool isHold;
        private void startHold(HandMode h)
        {
            if (h == HandMode.RightHand)
            {
                arc.Visibility = Visibility.Visible;
            }
            else if (h == HandMode.LeftHand)
            {
                arc_l.Visibility = Visibility.Visible;
            }
            isHold = true;
            waitToStartHold.Start();
        }
        private void endHold()
        {
            arc.Visibility = Visibility.Hidden;
            arc_l.Visibility = Visibility.Hidden;

            if (_handmode == HandMode.LeftHand)
            {
                holdLTimer.Stop();
            }
            else if (_handmode == HandMode.RightHand)
            {
                holdTimer.Stop();
            }
            isHold = false;
            setHandMode(HandMode.FreeHand);
 
        }
        private void finishedHold()
        {
        
            endHold();
            if (prevObjectHit != null)
            {
                if (prevObjectHit.Equals(HomeMenuIcon))
                {
                    toggleHomeMenu();
                }
                else if (prevObjectHit.Equals(menu))
                {
                    menu.finishHold();
                    toggleHomeMenu();
                }
                else if (prevObjectHit.Equals(content))
                {
                    UserControlInterfaceForGesture obj = (UserControlInterfaceForGesture)content;
                    obj.finishHold();
                }
            }
            isHold = false;
            

        }

        private void StartHoldBT_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	// TODO: Add event handler implementation here.
			//startHold();
        }
		
        private void Swipe_LeftBT_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	// TODO: Add event handler implementation here.

            if (!menu.IsToggle)
            {
                ((UserControlInterfaceForGesture)content).swipeLeft();
            }
			
        }

        private void Swipe_RightBT_Click(object sender, System.Windows.RoutedEventArgs e)
        {
           // ((UserControlInterfaceForGesture)content).swipeRight();
            if (!menu.IsToggle)
            {
                ((UserControlInterfaceForGesture)content).swipeRight();
            }
        }

        private void humanIn()
        {
            if (!isHumanVisible && isLoadFinished)
            {
                Storyboard st = (Storyboard)this.Resources["PointerFadeIn"];
                PointerCanvas.Visibility = Visibility.Visible;
                st.Begin();
                isHumanVisible = true;
                billboard_timer.Stop();
                if (typeof(BillBoard) == content.GetType())
                {
                    BillBoard b = (BillBoard)content;
                    b.stopAutoPlay();
                }
             
            }
        }
        private void humanOut()
        {
            if (isHumanVisible)
            {
              
                isHumanVisible = false;
                billboard_timer.Start();
                if (menu.IsToggle)
                {
                    menu.slideUp();
                    blurElement(false);
                }
             
            }

            
        }

    

        private void HumanInBT_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	// TODO: Add event handler implementation here.
      
            humanIn();
        }

        private void HumanOutBT_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	// TODO: Add event handler implementation here.
            humanOut();
        }

    }
}